home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / clients / xcalc / xcalc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-12  |  11.3 KB  |  397 lines

  1. /*
  2.  * $XConsortium: xcalc.c,v 1.15 91/02/16 19:39:37 converse Exp $
  3.  *
  4.  * xcalc.c  -  a hand calculator for the X Window system
  5.  * 
  6.  * Copyright 1989 by the Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided 
  10.  * that the above copyright notice appear in all copies and that both that 
  11.  * copyright notice and this permission notice appear in supporting 
  12.  * documentation, and that the name of M.I.T. not be used in advertising
  13.  * or publicity pertaining to distribution of the software without specific, 
  14.  * written prior permission. M.I.T. makes no representations about the 
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  20.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  21.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  22.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  *
  26.  *     Original Author:  John H. Bradley, University of Pennsylvania
  27.  *                (bradley@cis.upenn.edu)
  28.  *                  March, 1987
  29.  *  RPN mode added and port to X11 by Mark Rosenstein, MIT Project Athena
  30.  *  Rewritten to be an Xaw and Xt client by Donna Converse, MIT X Consortium
  31.  */
  32.  
  33. #include <stdio.h>
  34. #include <math.h>
  35. #include <signal.h>
  36. #ifdef MSDOS
  37. #include "X11/Intrinsc.h"      /* QDK 05/17/1994  3:17pm. */
  38. #else
  39. #include "X11/Intrinsic.h"
  40. #endif
  41. #include <X11/StringDefs.h>
  42. #include <X11/Xatom.h>
  43. #include <X11/Shell.h>
  44. #include <X11/Xaw/Cardinals.h>
  45. #include <X11/Xaw/Form.h>
  46. #include <X11/Xaw/Label.h>
  47. #include <X11/Xaw/Command.h>
  48. #include <X11/Xaw/Toggle.h>
  49. #include <X11/cursorfont.h>
  50. #include "xcalc.h"
  51. #include "actions.h"
  52.  
  53. #ifndef IEEE
  54. extern signal_t fperr();
  55. extern signal_t illerr();
  56. #endif
  57.  
  58. /*
  59.  *    global data
  60.  */
  61. int    rpn = 0;        /* Reverse Polish Notation (HP mode) flag */
  62. #define LCD_STR_LEN    32
  63. char    dispstr[LCD_STR_LEN];        /* string to show up in the LCD */
  64. Atom    wm_delete_window;        /* see ICCCM section 5.2.2 */
  65.  
  66. /*
  67.  *    local data
  68.  */
  69. static Display    *dpy = NULL;        /* connection to the X server */
  70. static Widget    toplevel=NULL;      /* top level shell widget */
  71. static Widget   calculator=NULL;    /* an underlying form widget */
  72. static Widget    LCD = NULL;        /* liquid crystal display */
  73. static Widget    ind[6];            /* mode indicators in the screen */
  74. static char    selstr[LCD_STR_LEN]; /* storage for selections from the LCD */
  75.                     /* checkerboard used in mono mode */
  76. static XtAppContext xtcontext;        /* Toolkit application context */
  77. #define check_width 16
  78. #define check_height 16
  79. static unsigned char check_bits[] = {
  80.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  81.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  82.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
  83.  
  84. /*    command line options specific to the application */
  85. static XrmOptionDescRec Options[] = {
  86. {"-rpn",    "rpn",        XrmoptionNoArg,        (XtPointer)"on"},
  87. {"-stipple",    "stipple",    XrmoptionNoArg,        (XtPointer)"on"}
  88. };
  89.  
  90. /*    resources specific to the application */
  91. static struct resources {
  92.     Boolean    rpn;        /* reverse polish notation (HP mode) */
  93.     Boolean    stipple;    /* background stipple */
  94.     Cursor    cursor;
  95. } appResources;
  96.  
  97. #define offset(field) XtOffsetOf(struct resources, field)
  98. static XtResource Resources[] = {
  99. {"rpn",        "Rpn",        XtRBoolean,    sizeof(Boolean),
  100.      offset(rpn),    XtRImmediate,    (XtPointer) False},
  101. {"stipple",    "Stipple",    XtRBoolean,    sizeof(Boolean),
  102.      offset(stipple),    XtRImmediate,    (XtPointer) False},
  103. {"cursor",    "Cursor",    XtRCursor,    sizeof(Cursor),
  104.      offset(cursor),    XtRCursor,    (XtPointer)NULL}
  105. };
  106. #undef offset
  107.  
  108.  
  109. void main(argc, argv)
  110.     int        argc;
  111.     char    **argv;
  112. {
  113.     Arg        args[3];
  114.  
  115.     void create_calculator();
  116.     void Quit(), Syntax();
  117.  
  118.  
  119.     toplevel = XtAppInitialize(&xtcontext, "XCalc", Options, XtNumber(Options),
  120.                    &argc, argv, NULL, NULL, 0);
  121.     if (argc != 1) Syntax(argc, argv);
  122.     
  123.     XtSetArg(args[0], XtNinput, True);
  124.     XtSetValues(toplevel, args, ONE);
  125.  
  126.     XtGetApplicationResources(toplevel, (XtPointer)&appResources, Resources,
  127.                   XtNumber(Resources), (ArgList) NULL, ZERO);
  128.  
  129.     create_calculator(toplevel);
  130.  
  131.     XtAppAddActions(xtcontext, Actions, XtNumber(Actions));
  132.  
  133.     XtOverrideTranslations(toplevel, 
  134.        XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()\n"));
  135.  
  136.     XtRealizeWidget(toplevel);
  137.  
  138.     dpy = XtDisplay(toplevel);
  139.     wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  140.     (void) XSetWMProtocols(dpy, XtWindow(toplevel), &wm_delete_window, 1);
  141.     XDefineCursor(dpy, XtWindow(toplevel), appResources.cursor);
  142.  
  143.     if (appResources.stipple || (CellsOfScreen(XtScreen(toplevel)) <= 2))
  144.     {
  145.     Screen    *screen = XtScreen(toplevel);
  146.     Pixmap    backgroundPix;
  147.  
  148.     backgroundPix = XCreatePixmapFromBitmapData
  149.         (dpy, XtWindow(toplevel),
  150.          (char *)check_bits, check_width, check_height,
  151.          WhitePixelOfScreen(screen), BlackPixelOfScreen(screen),
  152.          DefaultDepthOfScreen(screen));
  153.     XtSetArg(args[0], XtNbackgroundPixmap, backgroundPix);
  154.     XtSetValues(calculator, args, ONE);
  155.     }
  156.  
  157. #ifndef IEEE
  158.     signal(SIGFPE,fperr);
  159.     signal(SIGILL,illerr);
  160. #endif
  161.     ResetCalc();
  162.     XtAppMainLoop(xtcontext);
  163. }
  164.  
  165. void create_calculator(shell)
  166.     Widget    shell;
  167. {
  168.     void create_display();
  169.     void create_keypad();
  170.  
  171.     rpn = appResources.rpn;
  172.     calculator = XtCreateManagedWidget(rpn ? "hp" : "ti", formWidgetClass,
  173.                        shell, (ArgList) NULL, ZERO);
  174.     create_display(calculator);
  175.     create_keypad(calculator);
  176.     XtSetKeyboardFocus(calculator, LCD);
  177. }
  178.  
  179. /*
  180.  *    Do the calculator data display widgets.
  181.  */
  182. void create_display(parent)
  183.     Widget    parent;
  184. {
  185.     Widget    bevel, screen;
  186.     static Arg    args[] = {
  187.         {XtNborderWidth, (XtArgVal)0},
  188.         {XtNjustify, (XtArgVal)XtJustifyRight}
  189.     };
  190.  
  191.     /* the frame surrounding the calculator display */
  192.     bevel = XtCreateManagedWidget("bevel", formWidgetClass, parent,
  193.                   (ArgList) NULL, ZERO);
  194.  
  195.     /* the screen of the calculator */
  196.     screen = XtCreateManagedWidget("screen", formWidgetClass, bevel,
  197.                    (ArgList) NULL, ZERO);
  198.  
  199.     /* M - the memory indicator */
  200.     ind[XCalc_MEMORY] = XtCreateManagedWidget("M", labelWidgetClass, screen,
  201.                     args, XtNumber(args));
  202.  
  203.     /* liquid crystal display */
  204.     LCD = XtCreateManagedWidget("LCD", toggleWidgetClass, screen, args,
  205.                 XtNumber(args));
  206.  
  207.     /* INV - the inverse function indicator */
  208.     ind[XCalc_INVERSE] = XtCreateManagedWidget("INV", labelWidgetClass, 
  209.                      screen, args, XtNumber(args));
  210.  
  211.     /* DEG - the degrees switch indicator */
  212.     ind[XCalc_DEGREE] = XtCreateManagedWidget("DEG", labelWidgetClass, screen,
  213.                     args, XtNumber(args));
  214.  
  215.     /* RAD - the radian switch indicator */
  216.     ind[XCalc_RADIAN] = XtCreateManagedWidget("RAD", labelWidgetClass, screen,
  217.                     args, XtNumber(args));
  218.  
  219.     /* GRAD - the grad switch indicator */
  220.     ind[XCalc_GRADAM] = XtCreateManagedWidget("GRAD", labelWidgetClass, screen,
  221.                     args, XtNumber(args));
  222.  
  223.     /* () - the parenthesis indicator */
  224.     ind[XCalc_PAREN] = XtCreateManagedWidget("P", labelWidgetClass, screen,
  225.                          args, XtNumber(args));
  226. }
  227.  
  228. /*
  229.  *    Do all the buttons.  The application defaults file will give the
  230.  *    default button placement, default button labels, and default 
  231.  *      actions connected to the buttons.  The user can change any of 
  232.  *      these defaults in an environment-specific resource file.
  233.  */
  234.  
  235. void create_keypad(parent)
  236.     Widget    parent;
  237. {
  238.     static char    *Keyboard[] = {
  239.     "button1", "button2", "button3", "button4", "button5",
  240.     "button6", "button7", "button8", "button9", "button10",
  241.     "button11","button12","button13","button14","button15",
  242.     "button16","button17","button18","button19","button20",
  243.     "button21","button22","button23","button24","button25",
  244.     "button26","button27","button28","button29","button30",
  245.     "button31","button32","button33","button34","button35",
  246.     "button36","button37","button38","button39","button40"
  247.     };
  248.     register int i;
  249.     int         n = XtNumber(Keyboard);
  250.  
  251.     if (appResources.rpn) n--;     /* HP has 39 buttons, TI has 40 */
  252.  
  253.     for (i=0; i < n; i++)
  254.     XtCreateManagedWidget(Keyboard[i], commandWidgetClass, parent,
  255.                   (ArgList) NULL, ZERO);
  256. }
  257.  
  258. /*
  259.  *    Miscellaneous utility routines that interact with the widgets.
  260.  */
  261.  
  262. /*
  263.  *     called by math routines to write to the liquid crystal display.
  264.  */
  265. void draw(string)
  266.     char    *string;
  267. {
  268.     Arg    args[1];
  269.  
  270.     XtSetArg(args[0], XtNlabel, string);
  271.     XtSetValues(LCD, args, ONE);
  272. }
  273. /*
  274.  *    called by math routines to turn on and off the display indicators.
  275.  */
  276. void setflag(indicator, on)
  277.     int        indicator;
  278.     Boolean    on;
  279. {
  280.     if (on) XtMapWidget(ind[indicator]);
  281.     else XtUnmapWidget(ind[indicator]);
  282. }
  283.  
  284. /*
  285.  *    ring the bell.
  286.  */
  287. void ringbell()
  288. {
  289.     XBell(dpy, 0);
  290. }
  291.  
  292. /*
  293.  *    die.
  294.  */
  295. void Quit()
  296. {
  297. #ifndef MSDOS
  298.     extern void exit();
  299. #endif
  300.     XtDestroyApplicationContext(xtcontext);
  301.     exit(0);
  302. }
  303.  
  304. /*  
  305.  *    recite and die.
  306.  */
  307. void Syntax(argc, argv)    
  308.     int        argc;
  309.     char    **argv;
  310. {
  311.     register int i;
  312. #ifndef MSDOS
  313.     extern void exit();
  314. #endif
  315.     (void) fprintf(stderr, "%s: unknown options:", argv[0]);
  316.     for (i=1; i <argc; i++)
  317.     (void) fprintf(stderr, " %s", argv[i]);
  318.     (void) fprintf(stderr, "\n\n");
  319.     (void) fprintf(stderr, "Usage:  %s", argv[0]);
  320.     for (i=0; i < XtNumber(Options); i++)
  321.     (void) fprintf(stderr, " [%s]", Options[i].option);
  322.     (void) fprintf(stderr, "\n");
  323.     XtDestroyApplicationContext(xtcontext);
  324.     exit(1);
  325. }
  326.  
  327. /*    
  328.  * I use actions on the toggle widget to support selections.  This
  329.  * means that the user may not do a partial selection of the number
  330.  * displayed in the `liquid crystal display.'  Copying numbers into
  331.  * the calculator is also not supported.  So all you can do is copy
  332.  * the entire number from the calculator display.
  333.  */
  334.  
  335. /*ARGSUSED*/
  336. Boolean convert(w, selection, target, type, value, length, format)
  337.     Widget    w;
  338.     Atom    *selection;
  339.     Atom    *target;
  340.     Atom    *type;
  341.     XtPointer    *value;
  342.     unsigned long    *length;
  343.     int        *format;
  344. {
  345.     if (*target == XA_STRING)
  346.     {
  347.     *type = XA_STRING;
  348.     *length = strlen(dispstr);
  349.     strncpy(selstr, dispstr, (int)(*length));
  350.     *value = selstr;
  351.     *format = 8;
  352.     return True;
  353.     }
  354.     return False;
  355. }
  356.  
  357. /*
  358.  * called when xcalc loses ownership of the selection.
  359.  */
  360. /*ARGSUSED*/
  361. void lose(w, selection)
  362.     Widget    w;
  363.     Atom    *selection;
  364. {
  365.     XawToggleUnsetCurrent(LCD);
  366. }
  367.  
  368. /*
  369.  * called when some other client got the selection.
  370.  */
  371. /*ARGSUSED*/
  372. void done(w, selection, target)
  373.     Widget    w;
  374.     Atom    *selection;
  375.     Atom    *target;
  376. {
  377.     selstr[0] = '\0';
  378. }
  379.  
  380. /*
  381.  * called by the selection() action routine, in response to user action.
  382.  */
  383. void do_select(time)
  384.     Time    time;
  385. {
  386.     Boolean    state;
  387.     Arg        args[1];
  388.  
  389.     XtSetArg(args[0], XtNstate, &state);
  390.     XtGetValues(LCD, args, 1);
  391.  
  392.     if (state)
  393.         XtOwnSelection(LCD, XA_PRIMARY, time, convert, lose, done);
  394.     else
  395.     selstr[0] = '\0';
  396. }
  397.